/*
 * Copyright 2007 Matt Jensen
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.jtell.internal;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jtell.EventMetadata;
import org.jtell.EventMetadataSource;

import java.util.EventObject;

/**
 * <p>
 * <code>DefaultEventMetadataSource</code> is the default implementation of the {@link EventMetadataSource} interface.
 * The <code>event-class</code> attribute will always be the fully qualified class name of the event object. The
 * <code>source-class</code> will default to <code>java.lang.Object</code> unless the event object descends from
 * {@link EventObject}, in which case the <code>source</code> object will be extracted and its class returned
 * ({@link EventObject} does not allow <code>null</code> sources.)
 * </p>
 * <p>
 * <strong>Thread Safety</strong><br/>
 * Instances of this class are safe for multithreaded access, and all access is lock free.
 * </p>
 */
public class DefaultEventMetadataSource implements EventMetadataSource
{
    private static Log LOG = LogFactory.getLog(DefaultEventMetadataSource.class);

    /**
     * <p>
     * Construct a {@link DefaultEventMetadataSource} instance.
     * </p>
     */
    public DefaultEventMetadataSource()
    {
        super();
    }

    /* inherit javadoc */
    public EventMetadata getEventMetadata(final Object event)
    {
        // Get the event and source class names (we'll use a default if the source object is null or cannot be
        // determined.)
        final String eventClassName = ReflectionUtils.getApplicationClass(event.getClass()).getName();
        final String sourceClassName;
        if (!(event instanceof EventObject))
        {
            sourceClassName = Constants.DEFAULT_SOURCE_CLASS_NAME;
        }
        else
        {
            // Get the source from the EventObject; use the default if the source is null.
            final EventObject eventObject = (EventObject)event;
            sourceClassName = ReflectionUtils.getApplicationClass(eventObject.getSource().getClass()).getName();
        }

        // Create and return the metadata.
        final EventMetadata result = new EventMetadataImpl(eventClassName, sourceClassName, Empties.EMPTY_ATTRIBUTES);
        if (LOG.isDebugEnabled())
        {
            LOG.debug(String.format("Returning metadata [%s] for event [%s].", result, event));
        }
        return result;
    }
}
